package tools;

import net.sf.jsqlparser.parser.CCJSqlParserManager;
import net.sf.jsqlparser.statement.ShowStatement;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.create.function.CreateFunction;
import net.sf.jsqlparser.statement.create.table.ColumnDefinition;
import net.sf.jsqlparser.statement.create.table.CreateTable;
import net.sf.jsqlparser.statement.insert.Insert;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.select.SelectItem;
import net.sf.jsqlparser.statement.show.ShowTablesStatement;
import net.sf.jsqlparser.statement.update.Update;
import solutions.CreateSolution;
import solutions.InsertSolution;
import solutions.ShowSolution;

import java.io.IOException;
import java.io.StringReader;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Parser{

    public static boolean Validator(String str)
    {
        try{
            CCJSqlParserManager parserManager = new CCJSqlParserManager();
            Statement stat = parserManager.parse(new StringReader(str));
            return true;
        }catch(Exception e){

            return false;
        }
    }

    private static void parseSelect(Select select)
    {
        PlainSelect pl = (PlainSelect)select.getSelectBody();
        System.out.println(pl);
            System.out.println(pl.getFromItem());
        for (SelectItem item : pl.getSelectItems()) {
            System.out.println(item.toString());
        }

        System.out.println(pl.getWhere());



        System.out.println("this is a select statement");
    }

    private static void parseInsert(Insert insert)
    {
        if(SQLConstant.getDatabase() == null)
        {
            System.out.println("no database selected");
        }
        InsertSolution.Insert(SQLConstant.getRootpath(),SQLConstant.getDatabase(),insert.getTable().getName(), insert.getColumns(), insert.getValues().getExpressions());
        System.out.println("this is a Insert statement");
    }
    private static void parseCreateFunction(CreateTable create) throws IOException {
        if(SQLConstant.getDatabase() == null)
        {
            System.out.println("no database selected");
        }
        System.out.println("CREATE TABLE " + create.getTable());
        List<ColumnDefinition> columnDefinitions = create.getColumnDefinitions();
        CreateSolution.CreateTable(SQLConstant.getRootpath(), SQLConstant.getDatabase(), create.getTable().getName(), create.getColumnDefinitions());
    }
    public static void parse(String str)
    {

        try{
            //create databases
            String regex = "(?i)\\bCREATE\\s+DATABASE\\s+(\\w+)\\s*;?";
            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(str);
            if(matcher.matches()){
                CreateSolution.CreateDirectory(SQLConstant.getRootpath(), matcher.group(1));
                return;
            }

            //show databases
            regex = "(?i)\\bSHOW\\s+DATABASES\\s*;?";
            pattern = Pattern.compile(regex);
            matcher = pattern.matcher(str);
            if(matcher.matches()){
                ShowSolution.ShowDatabases(SQLConstant.getRootpath());
                return ;
            }

            //

            CCJSqlParserManager parserManager = new CCJSqlParserManager();
            Statement stat = parserManager.parse(new StringReader(str));
            if(stat instanceof Select) {
                Select select = (Select)stat;
//                parseSelect(select);
            }else if(stat instanceof Insert) {
                Insert insert = (Insert)stat;
                parseInsert(insert);
            }else if(stat instanceof Update) {
                Update update = (Update)stat;
            }
            else if(stat instanceof CreateTable) {
                CreateTable create = (CreateTable)stat;
                parseCreateFunction(create);
            }else if(stat instanceof ShowTablesStatement) {
                ShowSolution.ShowTables(SQLConstant.getRootpath() ,SQLConstant.getDatabase());
            }
            else{
                System.out.println(stat.getClass().getName());

            }
        }catch(Exception e){
            System.out.println(e.getMessage());
            System.out.println("invalid statement");
        }
    }


}